#pragma once
#include <TextBox.h>

class RoundTextBox : public TextBox
{
public:
	RoundTextBox(std::wstring text, int x, int y, int width = 120, int height = 24) : TextBox(text, x, y, width, height)
	{
		this->TextMargin = this->Height * 0.5f;
	}

public:
	void Update() override
	{
		if (this->IsVisual == false)
			return;
		bool isUnderMouse = this->MostParent->UnderMouse == this;
		auto d2d = this->Render;
		auto font = this->Font ? this->Font : d2d->DefaultFontObject;
		float render_height = this->Height - (TextMargin * 2.0f);
		textSize = font->GetTextSize(this->Text, FLT_MAX, render_height);
		float OffsetY = (this->Height - textSize.height) * 0.5f;
		if (OffsetY < 0.0f)
			OffsetY = 0.0f;
		auto abslocation = this->AbsLocation;
		auto size = this->ActualSize();
		auto absRect = this->AbsRect;
		bool isSelected = this->MostParent->Selected == this;
		d2d->PushDrawRect(absRect.left, absRect.top, absRect.right - absRect.left, absRect.bottom - absRect.top);
		{
			Control *tmpc = this;
			List<Control *> need_render_background;
			while (tmpc->BackColor.a < 1.0f)
			{
				tmpc = tmpc->Parent;
				need_render_background.Add(tmpc);
			}
			if (this->BackColor.a < 1.0f)
			{
				for (int i = need_render_background.Count - 1; i >= 0; i--)
				{
					d2d->FillRoundRect(abslocation.x, abslocation.y, size.cx, size.cy, need_render_background[i]->BackColor, this->TextMargin);
					if (need_render_background[i]->Image)
					{
						need_render_background[i]->RenderImage();
					}
				}
			}
			d2d->FillRoundRect(abslocation.x, abslocation.y, size.cx, size.cy, isSelected ? this->FocusedColor : this->BackColor, this->TextMargin);
			if (this->Image)
			{
				this->RenderImage();
			}
			if (this->Text.size() > 0)
			{

				auto font = this->Font ? this->Font : d2d->DefaultFontObject;
				if (isSelected)
				{
					int sels = SelectionStart <= SelectionEnd ? SelectionStart : SelectionEnd;
					int sele = SelectionEnd >= SelectionStart ? SelectionEnd : SelectionStart;
					int selLen = sele - sels;
					auto selRange = font->HitTestTextRange(this->Text, FLT_MAX, render_height, (UINT32)sels, (UINT32)selLen);
					if (selLen != 0)
					{
						for (auto sr : selRange)
						{
							d2d->FillRect(sr.left + abslocation.x + TextMargin - OffsetX, (sr.top + abslocation.y) - OffsetY, sr.width, sr.height, this->SelectedBackColor);
						}
					}
					else
					{
						d2d->DrawLine(
							{selRange[0].left + abslocation.x + TextMargin - OffsetX, (selRange[0].top + abslocation.y) - OffsetY},
							{selRange[0].left + abslocation.x + TextMargin - OffsetX, (selRange[0].top + abslocation.y + selRange[0].height) + OffsetY},
							Colors::Black);
					}
					d2d->DrawStringLayout(this->Text,
										  (float)abslocation.x + TextMargin - OffsetX, ((float)abslocation.y) + OffsetY,
										  FLT_MAX, render_height,
										  this->ForeColor,
										  DWRITE_TEXT_RANGE{(UINT32)sels, (UINT32)selLen},
										  this->SelectedForeColor,
										  font);
				}
				else
				{
					d2d->DrawStringLayout(this->Text,
										  (float)abslocation.x + TextMargin - OffsetX, ((float)abslocation.y) + OffsetY,
										  FLT_MAX, render_height,
										  this->ForeColor,
										  DWRITE_TEXT_RANGE{(UINT32)0, (UINT32)0},
										  this->SelectedForeColor,
										  font);
				}
			}
			else
			{
				if (isSelected)
					d2d->DrawLine(
						{(float)TextMargin + (float)abslocation.x - OffsetX, (float)abslocation.y + OffsetY},
						{(float)TextMargin + (float)abslocation.x - OffsetX, (float)abslocation.y + OffsetY + 16.0f},
						Colors::Black);
			}
			d2d->DrawRoundRect(abslocation.x + (this->Boder * 0.5f), abslocation.y + (this->Boder * 0.5f), size.cx - this->Boder, size.cy - this->Boder, this->BolderColor, this->Boder, this->TextMargin);
		}
		d2d->PopDrawRect();
	}
};
